import { LatLng, Point } from 'leaflet';
import Feature from '../feature/feature';
import { Selection } from 'd3-selection';
import Transform from '../geo/transform';
import NodesLayer from '../layer/nodesLayer';
import Mode from '../mode/mode';
import Vertex from '../feature/vertex';
import EventBus from '../util/eventBus';

/**
 * 要素类型
 */
export type FeatureType = 'polygon' | 'line' | 'point' | 'node';

/**
 * 底图类型
 */
export type MapType = 'vec' | 'img';

/**
 * 要素行为
 */
export type Behave = {
    annotation: string;
    features: Feature[];
    featuresJson?: FeatureJson[];
};

/**
 * 栈存储
 */
export type StackItem = {
    annotation: string; // 绘制的一个描述
    featureJson: FeatureJson; // 所有修改未保存的要素信息
    isBase?: boolean;
    map?: {
        // 底图状态
        center: [LatLng]; // 中心点
        zoom: number; // 底图级别
        type: MapType; // 底图类型
    };
};

/**
 * 要素转为json的类型
 */
export type FeatureJson = {
    id: string; // 唯一id
    latLngs: LatLng[] | LatLng[][]; // 地理坐标
    type: FeatureType; // 要素类型
    clasId?: string; // 分类代码
    properties?: any; // 要素属性
    style?: any; // 要素样式
};

export type FeatureInstance = {
    id: string; // 唯一id
    latLngs: LatLng[] | LatLng[][]; // 地理坐标,点是对象，多点是一维，线是一维，多线是二维，面是三维
    type: FeatureType; // 要素类型
    clasId?: string; // 分类代码
    properties?: any; // 要素属性
    style?: any; // 要素样式
    getInstanceType: () => string | undefined; // 获取实例类型'cross', 'vertex', 'point', 'line', 'polygon'
    changeId: (id: string) => FeatureInstance;
    setProperties: (props: any) => void;
    addMidPoint?: (position: { x: number; y: number }) => void;
    untie?: () => void;
    isEmpty: () => boolean;
};

/**
 * 模式类型
 */
export type ModeType = 'browse' | 'draw' | 'select' | 'drag';

export interface FeatureOption {
    transform: Transform;
    nodesLayer?: NodesLayer;
    mode: Mode;
    eventBus: EventBus;
    getAllActualFeatures: () => Map<string, Feature>;
    remove: (type: FeatureType, id: string) => Feature | undefined;
    addHistory(behave: Behave, isBase?: boolean): void;
    changeFeatureId: (oldId: string, newId: string) => Feature | undefined;
    transformFeature: (type: FeatureType, id: string) => Feature | undefined;
    changeMode: (modeType: ModeType, feature: Feature) => void;
    clipPath: (latLngs: LatLng[][]) => LatLng[][];
    featureMousedown: (e: MouseEvent, feature: Feature) => void;
    drawEnd?: (feature: Feature) => void;
    featureClick?: (e: MouseEvent, feature: Feature) => void;
    featureMousemove?: (e: MouseEvent, feature: Feature) => void;
    featureMouseout?: (e: MouseEvent, feature: Feature) => void;
    featureMouseup?: (e: MouseEvent, feature: Feature) => void;
    addVertex?: (
        latLng: LatLng,
        relateFeatures: Feature[],
        attr?: { size?: number; className?: string },
        judgeRepeat?: boolean,
        show?: boolean
    ) => string;
    getCrossPoint?: (
        feature: Feature,
        position: { x: number; y: number }
    ) => { point: L.Point; latLng: LatLng; index: number; sequence: number } | void;
}

/**
 * 图层参数
 */
export interface LayerOption extends FeatureOption {
    map: L.Map;
    surface: Selection<HTMLElement, unknown, null, undefined>;
}
